//接口 
(() => {
  //接口
  // 定义一个接口  该接口
  interface Iperson {
    //只读属性设置 不可更改
    readonly id: number,
    name: string,
    age: number,
    //? 表示 可有而无
    sex?: string
  }

  //定义一个对象  该对象的类型 就是定义的接口 Iperson
  const person: Iperson = {
    id: 1,
    name: '张三',
    age: 2,

  }
  console.log(person)
  // person.id = 90  id设置 只读  重新赋值会报错
  person.sex = '男'
  console.log(person)



  //函数类型
  /*
  为了使用接口表示函数类型   我们需要给接口定义一个调用签名
  它就像是一个只有参数列表和返回值类型的函数定义   参数列表中的每个参数都需要名字和指定类型
   */
  //定义一个接口  用来作为某个函数的类型来使用
  interface IsearchFunc {
    //定义一个调用签名
    (source: string, subing: string): boolean
  }

  //定义一个函数
  const searchString: IsearchFunc = function (source: string, subing: string): boolean {
    return source.search(subing) > -1
  }
  console.log(searchString('阿公公哈哈', '哈'))


  //类  类的类型可以通过 接口来实现
  //定义一个接口
  interface IMfly {
    //该方法没有任何的实现
    fly()
  }
  //定义一个类  该类的类型就是上面定义的接口(实际上可以是 IMfly约束了这个类)
  class Person implements IMfly {
    fly() {
      console.log('person1 fly')
    }
  }
  const person1 = new Person()
  person1.fly()

  //类  有一个或多个接口约束
  interface IMswi {
    swim()
  }

  //定义类
  class Person2 implements IMfly, IMswi {
    fly() {
      console.log('person2  fly')
    }
    swim() {
      console.log('person2   swim')
    }
  }

  const person2 = new Person2()
  person2.fly()
  person2.swim()



  //接口实现继承
  interface ImflyAndIMswim extends IMfly, IMswi { }

  //定义类
  class Person3 implements ImflyAndIMswim {
    fly() {
      console.log('person3  fly')
    }
    swim() {
      console.log('person3   swim')
    }
  }

  const person3 = new Person3()
  person3.fly()
  person3.swim()
})()